﻿namespace Marvin.Prediction
{
    /// <summary>
    /// This class encapsulates basic machine learning algorithms like linear regression and follows the template pattern.
    /// Right now, I'm just trying to get the basic algorithms online; I'm not designing this class with
    /// neural nets or PGMs in mind.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class PredictionAlgorithm: IPredictionAlgorithm
    {

        /// <summary>
        /// Trains the specified training set.
        /// </summary>
        /// <param name="trainingSet">The training set.</param>
        public void Train(TrainingSet<double> trainingSet)
        {
            TransformTrainingSetToInternalRepresentation(trainingSet); 
            NormalizeFeatures();
            Learn(); 
        }

        /// <summary>
        /// Learn parameters from the input data.
        /// </summary>
        protected abstract void Learn();

        /// <summary>
        /// Transforms the training set to internal representation.
        /// </summary>
        /// <param name="trainingSet">The training set.</param>
        protected abstract void TransformTrainingSetToInternalRepresentation(TrainingSet<double> trainingSet);


        /// <summary>
        /// Normalizes the features.
        /// </summary>
        virtual protected void NormalizeFeatures()
        {
            
        }


        /// <summary>
        /// Predicts the outcome for the specified input x.
        /// </summary>
        /// <param name="x">The input x.</param>
        /// <returns>the predicted outcome</returns>
        /// <exception cref="System.NotImplementedException">Please implement</exception>
        abstract public double Predict(double[] x);
    }
}
